package com.lt.lumentracks.service.Impl;

import com.lt.lumentracks.entity.po.User;
import com.lt.lumentracks.entity.po.UserBlacklist;
import com.lt.lumentracks.entity.vo.common.Result;
import com.lt.lumentracks.entity.vo.user.UserVO_conversationList;
import com.lt.lumentracks.mapper.UserBlacklistMapper;
import com.lt.lumentracks.service.IUserBlacklistService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lt.lumentracks.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 黑名单表，记录用户之间的拉黑情况 服务实现类
 * </p>
 *
 * @author swl
 * @since 2025-10-24
 */
@Service
public class UserBlacklistServiceImpl extends ServiceImpl<UserBlacklistMapper, UserBlacklist> implements IUserBlacklistService {

    @Autowired
    private IUserService iUserService;
    private static final Long MAX_BLACKLIST_COUNT = 50L;

    /** 拉黑 */
    @Override
    public Result<String> block(Integer userId, Integer targetId) {
        // 1. 不能拉黑自己
        if (userId.equals(targetId)) {
            return Result.error("不能拉黑自己");
        }

        // 2. 幂等：已拉黑就啥也不做
        Boolean alreadyBlocked = this.isBlocked(userId, targetId);
        if (alreadyBlocked) {
            return Result.success("已是拉黑状态");
        }

        // 3.达到拉黑用户数量限制则不拉黑
        Long count = lambdaQuery().eq(UserBlacklist::getUserId, userId).count();
        if (count >= MAX_BLACKLIST_COUNT) {
            return Result.error("已超过拉黑用户数量限制");
        }

        // 4. 真正插入
        UserBlacklist blk = new UserBlacklist();
        blk.setUserId(userId);
        blk.setBlockedId(targetId);
        blk.setCreateTime(LocalDateTime.now());
        // remark 可先空，后面让前端传

        boolean ok = save(blk);
        if (!ok) {
            return Result.error("拉黑失败，请稍后重试");
        }
        return Result.success("拉黑成功");
    }


    /** 取消拉黑 */
    @Override
    public Result<String> unblock(Integer userId, Integer targetId) {
        boolean ok = lambdaUpdate()
                .eq(UserBlacklist::getUserId, userId)
                .eq(UserBlacklist::getBlockedId, targetId)
                .remove();
        if (!ok) {
            return Result.error("取消拉黑失败或记录不存在");
        }
        return Result.success("取消拉黑成功");
    }


    /** 获取拉黑列表 */
    @Override
    public List<UserVO_conversationList> getBlockedList(Integer userId) {
        List<UserBlacklist> list = lambdaQuery().eq(UserBlacklist::getUserId, userId).list();
        if (list.isEmpty()) {
            return List.of();
        }
        List<Integer> targetIds = list.stream().map(UserBlacklist::getBlockedId).toList(); // 此前被当前用户拉黑的用户ID
        List<User> users = iUserService.listByIds(targetIds);
        Set<Integer> existingUserIds = users.stream().map(User::getId).collect(Collectors.toSet());

        // 已注销的用户ID
        List<Integer> nullUserIds = targetIds.stream().filter(id -> !existingUserIds.contains(id)).toList();

        // 已经注销的用户，则从黑名单中移除
        if (!nullUserIds.isEmpty()) {
            lambdaUpdate()
                    .eq(UserBlacklist::getUserId, userId)
                    .in(UserBlacklist::getBlockedId, nullUserIds)
                    .remove();
        }

        return users.stream().map(user -> {
            UserVO_conversationList vo = new UserVO_conversationList();
            vo.setId(user.getId());
            vo.setUsername(user.getUsername());
            vo.setAvatarUrl(user.getAvatarUrl());
            return vo;
        }).toList();
    }

    /**
     * 查询某用户是否拉黑了另一个用户
     * @param userId 拉黑者
     * @param targetId 被拉黑者
     * */
    @Override
    public Boolean isBlocked(Integer userId, Integer targetId) {
        return lambdaQuery()
                .eq(UserBlacklist::getUserId, userId)
                .eq(UserBlacklist::getBlockedId, targetId)
                .count() > 0;
    }

    /**
     * 获取某用户被哪些用户拉黑
     * @param targetId 被拉黑者
     * */
    @Override
    public Boolean isExistBlocked(Integer userId, Integer targetId) {
        return lambdaQuery()
                .and(wrapper -> wrapper
                        // 情况1：userId 拉黑了 targetId
                        .eq(UserBlacklist::getUserId, userId)
                        .eq(UserBlacklist::getBlockedId, targetId)
                )
                .or(wrapper -> wrapper
                        // 情况2：targetId 拉黑了 userId（反向关系）
                        .eq(UserBlacklist::getUserId, targetId)
                        .eq(UserBlacklist::getBlockedId, userId)
                )
                .count() > 0;
    }

}
